// 返回的函数并没有立刻执行，而是直到调用了f()才执行。我们来看一个例子：
//你可能认为调用f1()，f2()和f3()结果应该是1，4，9，但实际结果是：

// f1(); // 16
// f2(); // 16
// f3(); // 16
//使用let解决
function count() {
    var arr = [];
    for (let i = 1; i <= 3; i++) {
        arr.push(function() {
            return i * i;
        });
    }
    return arr;
}

var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
console.log(f1());

// 方法二是再创建一个函数，用该函数的参数绑定循环变量当前的值，无论该循环变量后续如何更改，已绑定到函数参数的值不变：

function count() {
    var arr = [];
    for (var i = 1; i <= 3; i++) {
        arr.push((function(n) {
            return function() {
                return n * n;
            }
        })(i));
    }
    return arr;
}

var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];

f1(); // 1
f2(); // 4
f3(); // 9
console.log(f1());

// 这里用了一个“创建一个匿名函数并立刻执行”的语法：

var f = (function(x) {
    return x * x;
})(3); // 9
console.log(f);


// 因此需要用括号把整个函数定义括起来：

(function(x) { return x * x })(3);


// 在面向对象的程序设计语言里，比如Java和C++，要在对象内部封装一个私有变量，可以用private修饰一个成员变量。

// 在没有class机制，只有函数的语言里，借助闭包，同样可以封装一个私有变量。我们用JavaScript创建一个计数器：

// 'use strict';

function create_counter(initial) {
    var x = initial || 0;
    return {
        inc: function() {

            return x += 1;
        }
    }
}

var c1 = create_counter();
c1.inc(); // 1
c1.inc(); // 2
c1.inc(); // 3

console.log(c1.inc());
var c2 = create_counter(10);
c2.inc(); // 11
c2.inc(); // 12
c2.inc(); // 13
console.log(c2.inc());



// 要计算xy可以用Math.pow(x, y)函数，不过考虑到经常计算x2或x3，我们可以利用闭包创建新的函数pow2和pow3：
function aa(n) {

    return (function(x) {
        return Math.pow(x, n);
    })

}

var a = aa(2);
console.log(a(5));



//箭头函数
x => x * x

// 上面的箭头函数相当于：

// function(x) {
//     return x * x;
// }

//打印方法
var a = x => ({
    name: '大帅比'
})
console.log(a.name);
// var a = x => {
//     return {
//         name: '大帅比'
//     }
// }

// 由于JavaScript函数对this绑定的错误处理，下面的例子无法得到预期结果：
// 现在，箭头函数完全修复了this的指向，this总是指向词法作用域，也就是外层调用者obj：
var gay = {
    brith: 2000,

    age: function() {
        var b = this.birth;


        var fc = () => new Date().getFullYear() - this.brith;

        return fc();
    }

}

console.log(gay.age());




// 练习 请使用箭头函数简化排序时传入的函数：

'use strict'
var arr = [10, 20, 1, 2];
arr.sort((x, y) => {
    if (x < y)
        return -1;
    if (x > y)
        return 1;


});
console.log(arr); // [1, 2, 10, 20]